<html xmlns="http://www.w3.org/1999/xhtml" id="input-devices">
<head>
  <title>入力デバイスと動作</title>
</head>

<body>

<h1>入力デバイスと動作</h1>

<!--=========================================================================-->
<!-- Major sub-heads in h2, etc                                                               -->
<!--=========================================================================-->
<h2>概要</h2>
<p>
この章では、Laszloアプリケーションにおいて、マウスとキーボード入力を具体化する方法を説明します。この章では、基本的なコンセプトと同時に、例えばマウスが押されている間に複数のビューにまたがってマウスをトラッキングするというような高度なトピックも扱っていきます。</p>

<h2>マウス</h2>

<p>
マウスを通じたビューとのやり取りは全てのアプリケーションの基本となるものです。これらのセクションでは基本的なコンセプトとともに、いくつかのより高度なトピックを展開していきます。</p>

<h3>基本的なマウスイベント</h3>
<p> 下に示す例のやり取りはViewが理解できる5つの基本的なイベントを示します。
</p> 
<p> <b>マウスイベント</b>: onmouseover、onmouseout、onmousedown、onmouseup、onclick </p>
<p>
onmouseup とonclickは似ていますが、onmouseupとはユーザがマウスを止めたときに送られ、一方onclickはユーザがマウスを止め、なおかつカーソルが依然Viewの境界内に含まれる時にのみ送られます。</p>

<example title="The basic mouse events" >
&lt;canvas height="40"&gt;
  &lt;view bgcolor="red"
        onmouseover="txt.setText('onmouseover')"
        onmouseout="txt.setText('onmouseout')"
        onmousedown="txt.setText('onmousedown')"
        onmouseup="txt.setText('onmouseup')"
        onclick="txt.setText('onmouseup, onclick')"
        x="10" y="10" width="20" height="20"/&gt;

  &lt;text id="txt"
        x="40" y="11" width="150"/&gt;
&lt;/canvas&gt;
</example>

<h3>Viewをクリック可能にする</h3>
<p>
Viewは、そのclickable属性がtrueの時にだけマウスイベントに対して反応を返します。Viewは、デフォルト状態ではクリック不可となっています。しかし、もし何らかのマウスイベントがViewのタグ内に（上記のように）含まれていれば、clickableは自動的にtrueにセットされます。次に示す例では、タグ自身の内部ではマウスイベントは宣言されておらず、メソッド内でのみ宣言されています。このような場合、Viewの clickableをtrueと明確に宣言することが必要となります。</p>

<example title="Making views clickable" >
&lt;canvas height="40"&gt;
  &lt;view bgcolor="red" clickable="true"
         x="10" y="10"
         width="20" height="20"&gt;
    &lt;method event="onmousedown"&gt;
      this.setWidth(30);
      this.setheight(30);
      this.setX(5);
      this.setY(5);
    &lt;/method&gt;
    &lt;method event="onmouseup"&gt;
      this.setWidth(20);
      this.setheight(20);
      this.setX(10);
      this.setY(10);
    &lt;/method&gt;
  &lt;/view&gt;
&lt;/canvas&gt;
</example>

<h3>カーソルマネージメント</h3>
<p>
クリック可能なViewの上に来ると、カーソルは自動的に手の形に変わりますが、もしカスタムカーソルを使いたければ、カーソル用にカスタムリソースを定義し、それを以下に示すようにLzCursorサービスで使用することで可能となります。

Example26.3.カーソルを変更する</p>

<example title="Changing the cursor">
&lt;canvas height="30"&gt;
  &lt;resource name="waitcursor" src="resources/lzwaitcursor_rsc.swf"/&gt;
  &lt;button onclick="setCursor()" text="Click me to change the cursor for 1/2 second"&gt;
    &lt;method name="setCursor"&gt;
      LzCursor.setCursorGlobal('waitcursor');
      // call LzCursor.restoreCursor() after 1/2 second
      var del= new LzDelegate(LzCursor, 'restoreCursor');
      LzTimer.addTimer(del, 500);
    &lt;/method&gt;
  &lt;/button&gt;
&lt;/canvas&gt;
</example>

<h4>手型のカーソルを無効にする</h4>
<p> LzCursor.showHandCursor() を true 、あるいは false にセットすることによって、全てのクリック可能な view に対して、手型のカーソルを表示したり非表示にしたりすることができます。 </p>
<p>この例では、手型のカーソルを表示/非表示を示しています。</p>
<example title="enabling and disabling the hand cursor">
&lt;canvas&gt;
    &lt;view width="100" height="100" bgcolor="green"&gt;
        &lt;method event="onclick"&gt;
            LzCursor.showHandCursor(true);
        &lt;/method&gt;
    &lt;/view&gt;
    &lt;view x="110" width="100" height="100" bgcolor="yellow"&gt;
        &lt;method event="onmouseover"&gt;
            LzCursor.showHandCursor(true);
        &lt;/method&gt;
        &lt;method event="onmouseout"&gt;
            LzCursor.showHandCursor(false);
        &lt;/method&gt;
    &lt;/view&gt;
    &lt;view x="220" width="100" height="100" bgcolor="red"&gt;
        &lt;method event="onclick"&gt;
            LzCursor.showHandCursor(false);
        &lt;/method&gt;
    &lt;/view&gt;
&lt;/canvas&gt;
</example>
<h3>カスタムボタン</h3>
<p>Conmouseup、onmouseover、onmousedownと状態に応じてイメージを変えるカスタムボタンを作るのはよくあることです。このトピックは、セクションで詳しくお話しますが、参考として<tagname link="true">basebutton</tagname>タグを使った例をここで紹介しておきます。</p>

<example title="Creating a custom button using basebutton">
&lt;canvas height="150"&gt;
  &lt;!-- first create the multi-frame resource and give it a name --&gt;
  &lt;resource name="mybutton_rsrc"&gt;
    &lt;!-- first frame MUST be the mouseup state of the button --&gt;     
    &lt;frame src="resources/button-up.png"/&gt;
    &lt;!-- second frame MUST be the mouseover state of the button --&gt;
    &lt;frame src="resources/button-over.png"/&gt;
    &lt;!-- third frame MUST be the mousedown state of the button --&gt;
    &lt;frame src="resources/button-down.png"/&gt;
  &lt;/resource&gt;
  
  &lt;!-- Second, assign the resource to a basebutton tag --&gt;
  &lt;basebutton resource="mybutton_rsrc"/&gt;
&lt;/canvas&gt;
</example>

<h3>Viewのドラッグ</h3>
<p>Viewをドラッグすることは、dragstateを使うことで可能となります。dragstateが適応されると、Viewは自由に、あるいは決められた軸の範囲内でドラッグすることができます。以下は、最大、最小、そして軸属性を持つdragstateの使用例です。</p>

<example title="dragging a view" >
&lt;canvas height="120"&gt;
  &lt;simplelayout spacing="3"/&gt;
  
  &lt;text&gt;dragging within a bounded area&lt;/text&gt;
  &lt;view bgcolor="yellow" height="40" width="160"&gt;
    &lt;view bgcolor="red" width="20" height="20" 
          onmousedown="this.dragger.apply()"
          onmouseup="this.dragger.remove()"&gt;
      &lt;dragstate name="dragger"
          drag_min_x="0"
          drag_max_x="$once{parent.width - this.width}"
          drag_min_y="0"
          drag_max_y="$once{parent.height - this.height}"
          drag_axis="both"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
  
  &lt;text&gt;dragging along the x-axis&lt;/text&gt;
  &lt;view bgcolor="yellow" height="40" width="160"&gt;
    &lt;view bgcolor="red" width="20" height="20" 
          onmousedown="this.dragger.apply()"
          onmouseup="this.dragger.remove()"&gt;
      &lt;dragstate name="dragger"
          drag_min_x="0"
          drag_max_x="$once{parent.width - this.width}"
          drag_min_y="0"
          drag_max_y="$once{parent.height - this.height}"
          drag_axis="x"/&gt;
    &lt;/view&gt;
  &lt;/view&gt;
 &lt;/canvas&gt;
</example>
<?ignore
<p>Having other views respond while a view is being dragged ... </p>

?>
<h2>マウスのトラッキング</h2>
<h3>単一View内でのマウスのトラッキング</h3>
<p>
この単純なプログラムは、View内での基本的なマウストラッキングの方法を示しています。
</p>
<example height="500" width="500" title="Simple mouse tracking">
&lt;canvas height="500" width="500" debug="true"&gt;
   &lt;debug y="300"/&gt;
   &lt;view width="300" height="300" bgcolor="red" clickable="true" &gt;
       &lt;attribute name="moustracker_del" value="$once{ new LzDelegate( this, 'trackmouse' )}" /&gt;
         &lt;method event="onmousedown" &gt;
           moustracker_del.register(LzIdle,'onidle');
       &lt;/method&gt;

       &lt;method event="onmouseup" &gt;
           moustracker_del.unregisterAll();
       &lt;/method&gt;

       &lt;method name="trackmouse" &gt;
           debug.write("mousex,mousey =", this.getMouse('x'),this.getMouse('y'));
       &lt;/method&gt;
         &lt;/view&gt;
&lt;/canvas&gt;
</example>
<p>
 これはたくさんのポイントを一般化していますが、trackmouseメソッドで、どれくらいのデータにフィルターをかけるか否かを決めることができます。
</p>

<h3>オーバラップされたView内でのマウスのトラッキング </h3>
<p>
特定のViewとの関連の中で、一旦マウスが押されると、onmouseoverとonmouseoutイベントが、そのViewにだけ送られます。これが、他のView上でのマウスの動きを追うことを難しくしています。この章では、まず始めにbasetrackgroupというベースコンポーネントを使い、それからbasetrackgroupの土台となっている低レベルAPIを使ってこの実行方法を説明します。</p>

<p>
以下の例で、nmouseover とonmouseoutイベントがViewのサイズを変えている一方で、onmousetrackover とonmousetrackoutイベントがViewの色を変えていることに注目してください。マウスをドラッグすると、最初のViewはそのサイズと色が変わりますが、他のViewでは色だけが変わります。繰り返しになりますが、これは基本のonmouseover とonmouseoutイベントがクリックされた最初のViewだけに送られているため起こるのです。</p>
<example title="Using basetrackgroup">
&lt;canvas height="160"&gt;
  &lt;class name="myTrackableView" bgcolor="red"
         onmouseover="setWidth(70)" 
         onmouseout="setWidth(60)"
         onmouseup="setAttribute('bgcolor', 0xFF0000)"
         width="60" height="30"&gt;

    &lt;!-- Use methods for mouse-tracking events --&gt;
    &lt;method event="onmousetrackover"&gt;
      setAttribute('bgcolor', 0x0000FF); //blue
    &lt;/method&gt;

    &lt;method event="onmousetrackout"&gt;
      setAttribute('bgcolor', 0xFF0000); //red
    &lt;/method&gt;

    &lt;method event="onmousetrackup"&gt;
      setAttribute('bgcolor', 0xFF0000); //red
    &lt;/method&gt;
  &lt;/class&gt;

  &lt;text&gt;Click on any red view and drag the mouse. &lt;/text&gt;
  &lt;basetrackgroup bgcolor="yellow"
                  x="20" y="40"&gt;
    &lt;myTrackableView/&gt;
    &lt;myTrackableView/&gt;
    &lt;myTrackableView/&gt;
    &lt;simplelayout axis="y" spacing="5"/&gt;
  &lt;/basetrackgroup&gt;
&lt;/canvas&gt;
</example>
<a name="view_source"/>
<h2>"View Source"右クリックメニュー要素</h2>
<p>
デフォルトのcanvasコンテクスト（右クリック）メニューは"view source"要素を持っており、Flashプレーヤーのバージョン7以降で有効です。デフォルトでは、このメニューはOpenLaszloウェブサイトへリンクする"About OpenLaszlo"エントリー、とviewソースへのオプションを含んでいます。</p>
<p>
For an application <tt>framitz.lzx</tt> that is deployed proxied（OpenLaszloサーバを使用して）、View Source上でのクリックが、新しいブラウザウィンドウ内で<tt>framitz.lzx?lzt=source</tt>を取得します。ソースを見せたくない場合には、WEB-INF/lps/config/lps.プロパティに<tt>allowRequestSOURCE=false </tt>をセットしてください。
</p>

<p style="background-color:#FF9900">この部分から下↓保留。本家にはない文章があったり、本家にある文章がなかったりしているので確定前に要確認。</p>

<p>
To preserve the "about OpenLaszlo" information while disabling source, you can use a method like the following, on the canvas:
</p>
<example extract="false" title="Disabling 'View Source'">
&lt;method event="oninit"&gt;
this.removeViewSourceMenu();
&lt;/method&gt;

&lt;method name="removeViewSourceMenu"&gt;
var cm1 = new ContextMenu();
cm1.hideBuiltInItems();
cm1.addItem(this.__LZdefaultMenuItem);
this.setContextMenu(cm1);
&lt;/method&gt;
</example>
<p>
SOLO deployed applications, say, <tt>framitz.lzx</tt>, will attempt to fetch <tt>"framitz.lzx.zip"</tt>.This assumes that a copy 
of the source will be placed there if you desire to make your source visible. If you don't wish to share code of your SOLO application, use the method above to disable the ViewSourceMenu.
</p>

<p style="background-color:#FF9900">保留ここまで。</p>


<h2>キーボード入力</h2>
<p>
OpenLaszloアプリケーションでは、キーボード"focus"を持つviewによって、キーボードからの入力が受け付けられます。<classname link="true">LzFocus</classname>サービスにより、focusをセットしたりコントロールしたりすることができます。Focusの逆は"blur"と言います。これについては以下でお話しします。</p>
<h3>FocusとLzFocusサービス</h3>
<p>
フォーカス可能なviewとは、<attribute>focusable</attribute>の属性がtrue（デフォルト値）になっているviewです。ユーザがフォーカス可能なviewをクリックすると、そのviewにフォーカスが当てられます。そのviewが以前にフォーカスされたviewとは異なる場合には、以前のviewには<event>onblur</event>が送られ、新しくフォーカスされたviewには<event>onfocus</event>が送られます。
</p>
<p>
キーボードからのviewへの入力を不可にするには、<code>focusable</code> の属性に"false"をセットします。</p>

<h3>フォーカストラップとフォーカスグループ</h3>
<p><dfn>Focus trap</dfn>: 
viewのフォーカストラップとは<attribute>focustrap</attribute>属性がtrueである最も直接の祖先、あるいはcanvasのことです。viewの<dfn>focus
group</dfn>とは、フォーカストラップの子孫であり、<attribute>focustrap</attribute>属性がtrueである一番近い祖先の子孫ではないフォーカス可能なviewの集まりのことです。
</p>

<p>
この定義の趣旨は、ウィンドウのように<attribute>focustrap</attribute>がtrueであるviewの子の内部でのtabbingは、同じviewの他の子にはタブを付けるけれど、他のウィンドウ内のviewにはタブを付けないということです。
</p>

<p><a href="${demos}contacts">Contacts demo</a>は、キーボードフォーカスの使い方を説明します。詳細ウィンドウを開くために、名前をダブルクリックしてください。テキスト内をクリックし、同じフォーカスグループ内の別のテキストフィールドに移動するためにタブとシフトタブとを押してください。
</p>
<h4>フォーカスグループ内での移動にタブキーを使う</h4>
<p>タブキーが押されると、フォーカスは現在の<i>focus group</i>内にある次のフォーカス可能なviewへと移動します。次のviewがない場合には、そのフォーカスグループ内の最初のviewが選択されます。同じように、シフトタブでは、前のフォーカス可能なviewが選択されます。前のviewがない場合には、そのフォーカスグループ内の最後のviewが選択されます。
</p>

<p>
デフォルトの動きを変更するために、viewは<method>getNextSelection</method> と<method>getPrevSelection</method>メソッドをオーバーライドすることができます。タブやシフトタブキーは、現在キーボードフォーカスを持つview上の<method>getNextSelection</method> と <method>getPrevSelection</method>を呼ぶことによって、返されたviewを選択します。
</p>
<h4>フォーカスグループのプログラム的コントロール</h4>
<p>
タブキーに加え、フォーカスグループ内のフォーカスは、<a
href="#meth-setFocus">LzFocus.setFocus</a>、<a href="#meth-next">LzFocus.next</a>、<a href="#meth-prev">LzFocus.prev</a>メソッドを呼ぶことでプログラム的にコントロールすることもできます。
</p>
<h3>キーの値を読む</h3>
<p>
キーボード入力をアプリケーションに組み入れる一つの方法として、フォーカス可能なviewに押されたキーのコードを保存させるというやり方があります。一度に一つのviewだけがフォーカス可能となりえます。この例では、oninitで該当viewにフォーカスを当てています（より大きなアプリケーションでは、タブキーを使って該当viewにフォーカスを合わせるか、あるいはフォーカスを合わせるようにするためのonclickメソッドを書くこともできます）。</p>
<p>
以下の例では、viewがキーボード入力を受け付けるようにするための<tagname>LzFocus</tagname>の使い方を説明しています。
</p>
<example title="Reading Key Values">
&lt;canvas  height="200" debug="true"&gt;
    &lt;debug x="110" y="15" /&gt;

    &lt;!-- NOTE: Even though the view below takes focus oninit,
               in some browsers you might still need to click on the
               application itself, to take the focus away from the 
               browser itself and to the Flash Player. --&gt;

    &lt;view width="100" height="100" bgcolor="0x333399"
          focusable="true"
          oninit="LzFocus.setFocus(this)"&gt;

        &lt;method event="oninit"&gt;
            this.keyCodes = new Array()
            this.keyCodes[65] = "A for Apple";
            this.keyCodes[76] = "L for Laszlo";
            this.keyCodes[79] = "O for Optometrist";
            this.keyCodes[83] = "S for Sammy";
            this.keyCodes[90] = "Z for Zebra";
        &lt;/method&gt;

        &lt;method event="onkeydown" args="akeycode"&gt;
            // respond here    
            Debug.write( "Key pressed: " + akeycode );
            if ( this.keyCodes[akeycode] != undefined ) {
                Debug.write( this.keyCodes[akeycode] );
            } else {
                Debug.write( "you pressed: " + String.fromCharCode(akeycode) );
            }
        &lt;/method&gt;
    &lt;/view&gt;
&lt;/canvas&gt;
</example>
<?ignore
<example title="Creating and using LzTrackgroups">

</example>
<!--
<h4>Tracking APIs</h4>
-->

<todo>
<h2>The Keyboard ( section under construction )</h2>

<h3>Focusing on a View</h3>
<h3>Basic Keyboard Events</h3>
<h3>While the Key is down...</h3>
<h3>Using Modifier keys: Option, Shift, and Control</h3>
</todo>
?>
</body>
</html>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2001-2004 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
